package iks.net.codec
{
	import flash.utils.*;
	import iks.exception.*;
	
	/**
	 * 基于帧头数据帧长度的解码器
	 * @author Kaka
	 */
	public final class LengthDecode implements IChannelDecode
	{
		/**
		 * 构造函数
		 * @param	skipLengthField 跳过的数据域字节长度
		 * @param	dataLengthField 标志数据长度的长度域
		 */
		public function LengthDecode(skipFieldLength : int, dataFieldLength : int) 
		{
			m_skipFieldLength = skipFieldLength;
			
			if (dataFieldLength == 1 || dataFieldLength == 2 || dataFieldLength == 4)
			{
				m_dataFieldLength = dataFieldLength;
			}
			else
			{
				throw new DataLengthError("数据长度域参数错误, 只能使用(1, 2, 4): " + dataFieldLength);
			}
			
			m_buffer = new ByteArray();
		}
		
		/**
		 * 分析数据包
		 * @param message 字节序列
		 * @return 如果将包解析了返回解析字节序列, 否则返回null
		 */
		public function decodeData(message : ByteArray) : ByteArray
		{
			// 读取 省略字节域
			if (!m_isSkipHead && message.bytesAvailable != 0)
			{
				if (m_skipFieldLength == 0)	// 如果省略字节域不需要读, 则直接读过省略域
				{
					m_isSkipHead = true;
				}
				else if (message.bytesAvailable >= m_skipFieldLength)	// 读完整个 省略字节域 的长度
				{
					message.readBytes(m_buffer, m_buffer.length, m_skipFieldLength - m_buffer.length);
					m_isSkipHead = true;
					m_buffer = new ByteArray();
				}
				else	// 将剩余的字节读完
				{
					message.readBytes(m_buffer, m_buffer.length, message.bytesAvailable);
					return null;
				}
			}
			
			// 读取 数据长度域
			if (!m_isReadHead && message.bytesAvailable != 0)
			{
				// 将数据长度域读完
				if (message.bytesAvailable >= m_dataFieldLength)
				{
					message.readBytes(m_buffer, m_buffer.length, m_dataFieldLength - m_buffer.length);
					m_isReadHead = true;
					switch (m_dataFieldLength)
					{
						case 1:
							m_readLength = m_buffer.readUnsignedByte();
							break;
							
						case 2:
							m_readLength = m_buffer.readUnsignedShort();
							break;
							
						case 4:
							m_readLength = m_buffer.readUnsignedInt();
							break;
					}
					m_buffer = new ByteArray();
				}
				else
				{
					// 将剩余的字节读完
					message.readBytes(m_buffer, m_buffer.length, message.bytesAvailable);
					return null;
				}
			}
			
			// 当有可读字节的时候才读取数据
			if (message.bytesAvailable == 0)
				return null;
			
			// 读取数据字节
			if (message.bytesAvailable >= m_readLength)
			{
				message.readBytes(m_buffer, m_buffer.length, m_readLength);
				m_isSkipHead = false;
				m_isReadHead = false;
				var tmp : ByteArray = m_buffer;
				m_buffer = new ByteArray();
				return tmp;
			}
			else
			{
				m_readLength -= message.bytesAvailable;
				message.readBytes(m_buffer, m_buffer.length, message.bytesAvailable);
				return null;
			}
		}
		
		private var m_skipFieldLength : int = 0;
		private var m_dataFieldLength : int = 0;
		
		private var m_isSkipHead : Boolean = false;
		private var m_isReadHead : Boolean = false;
		private var m_readLength : uint = 0;
		private var m_buffer : ByteArray = null;
	}

}